package com.adk.backend.service.impl;

import com.adk.backend.entity.LxServiceList;
import com.adk.backend.entity.LxBillingList;
import com.adk.backend.entity.LxBillingDetails;
import com.adk.backend.entity.LxFeeType;
import com.adk.backend.entity.LxUnitList;
import com.adk.backend.mapper.ServiceListMapper;
import com.adk.backend.mapper.BillingListMapper;
import com.adk.backend.mapper.BillingDetailsMapper;
import com.adk.backend.mapper.FeeTypeMapper;
import com.adk.backend.mapper.UnitListMapper;
import com.adk.backend.service.ServiceListService;
import com.adk.backend.util.FileUploadUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 服务列表服务实现类
 */
@Slf4j
@Service
public class ServiceListServiceImpl implements ServiceListService {
    
    @Autowired
    private ServiceListMapper serviceListMapper;
    
    @Autowired
    private BillingListMapper billingListMapper;
    
    @Autowired
    private BillingDetailsMapper billingDetailsMapper;
    
    @Autowired
    private FeeTypeMapper feeTypeMapper;
    
    @Autowired
    private UnitListMapper unitListMapper;
    
    @Autowired
    private FileUploadUtil fileUploadUtil;
    
    @Override
    public List<Map<String, Object>> getServiceList(Map<String, Object> params) {
        return serviceListMapper.selectServiceListWithCustomer(params);
    }
    
    @Override
    public Map<String, Object> getServiceDetailById(Long id) {
        return serviceListMapper.selectServiceDetailById(id);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveService(LxServiceList service) {
        try {
            if (service.getId() != null && service.getId() > 0) {
                // 更新：设置更新用户ID和更新时间
                // 注意：updateUid 和 updateTime 应该在Controller中设置，这里保留接口灵活性
                serviceListMapper.updateById(service);
            } else {
                // 新增
                if (service.getStatus() == null) {
                    service.setStatus(1); // 默认待处理
                }
                if (service.getAddTime() == null) {
                    service.setAddTime((int) (System.currentTimeMillis() / 1000));
                }
                serviceListMapper.insert(service);
            }
            return true;
        } catch (Exception e) {
            log.error("保存服务失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteService(Long id) {
        try {
            LxServiceList service = serviceListMapper.selectById(id);
            if (service != null) {
                // 删除附件
                if (service.getAttr() != null && !service.getAttr().isEmpty()) {
                    String[] files = service.getAttr().split(",");
                    for (String file : files) {
                        if (file != null && !file.trim().isEmpty()) {
                            fileUploadUtil.deleteLocalFile("./uploads/service/u/" + file.trim());
                        }
                    }
                }
                // 删除登记附件
                if (service.getRAttr() != null && !service.getRAttr().isEmpty()) {
                    String[] files = service.getRAttr().split(",");
                    for (String file : files) {
                        if (file != null && !file.trim().isEmpty()) {
                            fileUploadUtil.deleteLocalFile("./uploads/service/u/" + file.trim());
                        }
                    }
                }
                serviceListMapper.deleteById(id);
            }
            return true;
        } catch (Exception e) {
            log.error("删除服务失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateServiceStatus(Long id, Integer status, String bookingDate, String rRemarks, String rAttr, Integer userId) {
        try {
            LxServiceList service = serviceListMapper.selectById(id);
            if (service == null) {
                return false;
            }
            
            if (status != null) {
                service.setStatus(status);
            }
            if (bookingDate != null && !bookingDate.isEmpty()) {
                service.setBookingDate(bookingDate);
                try {
                    service.setBookingDateInt((int) (java.sql.Date.valueOf(bookingDate).getTime() / 1000));
                } catch (Exception e) {
                    log.error("日期转换失败", e);
                }
            }
            if (rRemarks != null) {
                service.setRRemarks(rRemarks);
            }
            if (rAttr != null) {
                // 删除旧的登记附件
                if (service.getRAttr() != null && !service.getRAttr().isEmpty()) {
                    String[] oldFiles = service.getRAttr().split(",");
                    for (String file : oldFiles) {
                        if (file != null && !file.trim().isEmpty()) {
                            fileUploadUtil.deleteLocalFile("./uploads/service/u/" + file.trim());
                        }
                    }
                }
                service.setRAttr(rAttr);
            }
            service.setRUid(userId);
            service.setRTime((int) (System.currentTimeMillis() / 1000));
            
            serviceListMapper.updateById(service);
            return true;
        } catch (Exception e) {
            log.error("更新服务状态失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAttachment(Long id, String fileName, Integer userId) {
        try {
            LxServiceList service = serviceListMapper.selectById(id);
            if (service == null) {
                return false;
            }
            
            // 删除文件
            fileUploadUtil.deleteLocalFile("./uploads/service/u/" + fileName);
            
            // 更新附件列表
            String attr = service.getAttr();
            if (attr != null && !attr.isEmpty()) {
                String[] files = attr.split(",");
                List<String> newFiles = new ArrayList<>();
                for (String file : files) {
                    String trimmedFile = file.trim();
                    if (!trimmedFile.equals(fileName) && !trimmedFile.isEmpty()) {
                        newFiles.add(trimmedFile);
                    }
                }
                if (newFiles.isEmpty()) {
                    service.setAttr(null);
                } else {
                    service.setAttr(String.join(",", newFiles));
                }
                serviceListMapper.updateById(service);
            }
            
            return true;
        } catch (Exception e) {
            log.error("删除附件失败", e);
            return false;
        }
    }
    
    /**
     * 上传多个文件到本地（服务管理专用）
     * 文件名格式：userId-timestamp序号.扩展名（如：1-12345678911.pdf）
     */
    public String uploadServiceFiles(org.springframework.web.multipart.MultipartFile[] files, Integer userId) {
        if (files == null || files.length == 0) {
            return null;
        }
        
        List<String> uploadedFiles = new ArrayList<>();
        long timestamp = System.currentTimeMillis() / 1000;
        
        for (int i = 0; i < files.length; i++) {
            org.springframework.web.multipart.MultipartFile file = files[i];
            if (file == null || file.isEmpty()) {
                continue;
            }
            
            try {
                String originalFilename = file.getOriginalFilename();
                if (originalFilename == null) {
                    continue;
                }
                
                // 获取文件扩展名
                String extension = "";
                if (originalFilename.contains(".")) {
                    extension = originalFilename.substring(originalFilename.lastIndexOf("."));
                }
                
                // 验证文件类型
                String lowerExtension = extension.toLowerCase();
                String[] allowedTypes = {"pdf", "jpg", "jpeg", "png", "xlsx", "xls", "csv", "txt", "7z", "zip", "rar"};
                boolean isValidType = false;
                for (String type : allowedTypes) {
                    if (lowerExtension.equals("." + type)) {
                        isValidType = true;
                        break;
                    }
                }
                if (!isValidType) {
                    log.warn("不支持的文件类型: {}", originalFilename);
                    continue;
                }
                
                // 创建上传目录
                java.io.File uploadDir = new java.io.File("uploads/service/u");
                if (!uploadDir.exists()) {
                    uploadDir.mkdirs();
                }
                
                // 生成文件名：userId-timestamp序号.扩展名（PHP格式）
                int fileNum = i + 1;
                String fileName = userId + "-" + timestamp + fileNum + extension;
                
                // 保存文件
                java.io.File targetFile = new java.io.File(uploadDir, fileName);
                file.transferTo(targetFile);
                
                uploadedFiles.add(fileName);
            } catch (Exception e) {
                log.error("上传文件失败: {}", file.getOriginalFilename(), e);
                // 继续处理其他文件
            }
        }
        
        if (uploadedFiles.isEmpty()) {
            return null;
        }
        
        return String.join(",", uploadedFiles);
    }
    
    /**
     * 上传登记附件（带R前缀）
     * 文件名格式：userId-R-timestamp序号.扩展名（如：1-R-12345678911.pdf）
     */
    public String uploadServiceRAttrFiles(org.springframework.web.multipart.MultipartFile[] files, Integer userId) {
        if (files == null || files.length == 0) {
            return null;
        }
        
        List<String> uploadedFiles = new ArrayList<>();
        long timestamp = System.currentTimeMillis() / 1000;
        
        for (int i = 0; i < files.length; i++) {
            org.springframework.web.multipart.MultipartFile file = files[i];
            if (file == null || file.isEmpty()) {
                continue;
            }
            
            try {
                String originalFilename = file.getOriginalFilename();
                if (originalFilename == null) {
                    continue;
                }
                
                // 获取文件扩展名
                String extension = "";
                if (originalFilename.contains(".")) {
                    extension = originalFilename.substring(originalFilename.lastIndexOf("."));
                }
                
                // 验证文件类型
                String lowerExtension = extension.toLowerCase();
                String[] allowedTypes = {"pdf", "jpg", "jpeg", "png", "xlsx", "xls", "csv", "txt", "7z", "zip", "rar"};
                boolean isValidType = false;
                for (String type : allowedTypes) {
                    if (lowerExtension.equals("." + type)) {
                        isValidType = true;
                        break;
                    }
                }
                if (!isValidType) {
                    log.warn("不支持的文件类型: {}", originalFilename);
                    continue;
                }
                
                // 创建上传目录
                java.io.File uploadDir = new java.io.File("uploads/service/u");
                if (!uploadDir.exists()) {
                    uploadDir.mkdirs();
                }
                
                // 生成文件名：userId-R-timestamp序号.扩展名（PHP格式）
                int fileNum = i + 1;
                String fileName = userId + "-R-" + timestamp + fileNum + extension;
                
                // 保存文件
                java.io.File targetFile = new java.io.File(uploadDir, fileName);
                file.transferTo(targetFile);
                
                uploadedFiles.add(fileName);
            } catch (Exception e) {
                log.error("上传登记附件失败: {}", file.getOriginalFilename(), e);
            }
        }
        
        if (uploadedFiles.isEmpty()) {
            return null;
        }
        
        return String.join(",", uploadedFiles);
    }
    
    @Override
    public Map<String, Object> getBillingInfo(Long serviceId) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取服务信息
        LxServiceList service = serviceListMapper.selectById(serviceId);
        if (service == null) {
            throw new RuntimeException("服务不存在");
        }
        
        result.put("serviceId", service.getId());
        result.put("customerId", service.getCId());
        result.put("bookingDateInt", service.getBookingDateInt());
        result.put("billingId", service.getBillingId());
        result.put("billingAmount", service.getBillingAmount());
        
        // 获取账单信息
        Long billingId = service.getBillingId();
        if (billingId != null && billingId > 0) {
            LxBillingList billing = billingListMapper.selectById(billingId);
            if (billing != null) {
                result.put("exchangeRateSar", billing.getExchangeRateSar());
                result.put("exchangeRateUsd", billing.getExchangeRateUsd());
                result.put("billRemarks", billing.getRemarks());
                result.put("paid", billing.getPaid());
            }
        }
        
        // 获取账单明细
        List<Map<String, Object>> details = new ArrayList<>();
        if (billingId != null && billingId > 0) {
            List<LxBillingDetails> billingDetails = billingDetailsMapper.selectByBillId(billingId);
            for (LxBillingDetails detail : billingDetails) {
                Map<String, Object> detailMap = new HashMap<>();
                detailMap.put("id", detail.getId());
                detailMap.put("feeType", detail.getFeeType());
                detailMap.put("shipWeigthNum", detail.getShipWeigthNum());
                detailMap.put("price", detail.getPrice());
                detailMap.put("currencyId", detail.getCurrencyId());
                detailMap.put("unitId", detail.getUnitId());
                detailMap.put("exchangeRateSar", detail.getExchangeRateSar());
                detailMap.put("exchangeRate", detail.getExchangeRateSar()); // 用于前端显示
                
                // 查询费用类型名称
                if (detail.getFeeType() != null) {
                    LxFeeType feeType = feeTypeMapper.selectById(detail.getFeeType());
                    if (feeType != null) {
                        detailMap.put("feeName", feeType.getFeeName());
                    }
                }
                
                // 查询单位名称
                if (detail.getUnitId() != null) {
                    LxUnitList unit = unitListMapper.selectById(detail.getUnitId());
                    if (unit != null) {
                        detailMap.put("unitName", unit.getUnitName());
                    }
                }
                
                details.add(detailMap);
            }
        }
        result.put("details", details);
        
        // 查询费用类型列表（type=8，用于服务账单）
        QueryWrapper<LxFeeType> feeTypeWrapper = new QueryWrapper<>();
        feeTypeWrapper.eq("type", 8).orderByAsc("id");
        List<LxFeeType> feeTypes = feeTypeMapper.selectList(feeTypeWrapper);
        result.put("feeTypes", feeTypes);
        
        // 查询单位列表
        List<LxUnitList> units = unitListMapper.selectList(new QueryWrapper<>());
        result.put("units", units);
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBilling(Long serviceId, Map<String, Object> billingData, Integer userId) {
        try {
            // 获取服务信息
            LxServiceList service = serviceListMapper.selectById(serviceId);
            if (service == null) {
                throw new RuntimeException("服务不存在");
            }
            
            // 检查预约日期
            if (service.getBookingDateInt() == null || service.getBookingDateInt() <= 0) {
                throw new RuntimeException("错误,没有预约时间无法出账单");
            }
            
            // 检查是否已创建账单
            QueryWrapper<LxBillingList> wrapper = new QueryWrapper<>();
            wrapper.eq("order_id", serviceId).eq("ship_type", 8);
            LxBillingList existingBill = billingListMapper.selectOne(wrapper);
            
            Long billingId;
            boolean isNew = (existingBill == null);
            
            if (isNew) {
                // 创建新账单
                LxBillingList billing = new LxBillingList();
                billing.setOrderId(serviceId);
                billing.setCustomerId(service.getCId());
                billing.setCurrencyId(1); // RMB
                billing.setShipType(8); // 服务账单
                billing.setBillDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                billing.setBillDateInt((long) (System.currentTimeMillis() / 1000));
                billing.setRecvTime(service.getBookingDateInt());
                billing.setAddUid((long) userId);
                billing.setAddTime((int) (System.currentTimeMillis() / 1000));
                billing.setExchangeRateSar(((BigDecimal) billingData.getOrDefault("exchangeRateSar", BigDecimal.ONE)));
                billing.setExchangeRateUsd(((BigDecimal) billingData.getOrDefault("exchangeRateUsd", BigDecimal.ONE)));
                billing.setRemarks((String) billingData.getOrDefault("billRemarks", ""));
                billing.setIsReceivable(1);
                
                billingListMapper.insert(billing);
                billingId = billing.getId();
                
                // 更新服务
                service.setBillingId(billingId);
                service.setIsBill(1);
                service.setBillUid(userId);
                service.setBillTime((int) (System.currentTimeMillis() / 1000));
                serviceListMapper.updateById(service);
            } else {
                billingId = existingBill.getId();
                
                // 检查是否已付款（需要授权码，这里简化处理）
                if (existingBill.getPaid() != null && existingBill.getPaid() == 1) {
                    // 如果需要授权码验证，可以在这里添加
                }
                
                // 重新获取账单确保不为null
                LxBillingList billToUpdate = billingListMapper.selectById(billingId);
                if (billToUpdate != null) {
                    // 更新账单
                    billToUpdate.setUpdateUid(userId);
                    billToUpdate.setUpdateTime((int) (System.currentTimeMillis() / 1000));
                    billToUpdate.setExchangeRateSar(((BigDecimal) billingData.getOrDefault("exchangeRateSar", BigDecimal.ONE)));
                    billToUpdate.setExchangeRateUsd(((BigDecimal) billingData.getOrDefault("exchangeRateUsd", BigDecimal.ONE)));
                    billToUpdate.setRemarks((String) billingData.getOrDefault("billRemarks", ""));
                    billToUpdate.setIsReceivable(1);
                    billingListMapper.updateById(billToUpdate);
                }
                
                // 更新服务
                service.setBillUid(userId);
                service.setBillTime((int) (System.currentTimeMillis() / 1000));
                serviceListMapper.updateById(service);
            }
            
            // 处理账单明细
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> details = (List<Map<String, Object>>) billingData.get("details");
            if (details != null) {
                BigDecimal totalAmount = BigDecimal.ZERO;
                
                for (Map<String, Object> detail : details) {
                    Long detailId = detail.get("id") != null ? 
                        Long.valueOf(detail.get("id").toString()) : null;
                    
                    Integer feeType = Integer.valueOf(detail.get("feeType").toString());
                    BigDecimal shipWeigthNum = new BigDecimal(detail.get("shipWeigthNum").toString());
                    BigDecimal price = new BigDecimal(detail.get("price").toString());
                    Integer currencyId = Integer.valueOf(detail.get("currencyId").toString());
                    Integer unitId = detail.get("unitId") != null ? 
                        Integer.valueOf(detail.get("unitId").toString()) : null;
                    BigDecimal exchangeRate = new BigDecimal(detail.getOrDefault("exchangeRate", "1").toString());
                    
                    if (detailId != null && detailId > 0) {
                        // 更新
                        LxBillingDetails billingDetail = billingDetailsMapper.selectById(detailId);
                        if (billingDetail != null) {
                            billingDetail.setPrice(price);
                            billingDetail.setShipWeigthNum(shipWeigthNum);
                            billingDetail.setExchangeRateSar(exchangeRate);
                            billingDetailsMapper.updateById(billingDetail);
                        }
                    } else {
                        // 新增
                        LxBillingDetails billingDetail = new LxBillingDetails();
                        billingDetail.setBillId(billingId);
                        billingDetail.setOrderId(serviceId);
                        billingDetail.setFeeType(feeType);
                        billingDetail.setShipWeigthNum(shipWeigthNum);
                        billingDetail.setPrice(price);
                        billingDetail.setCurrencyId(currencyId);
                        billingDetail.setUnitId(unitId);
                        billingDetail.setExchangeRateSar(exchangeRate);
                        billingDetail.setExchangeRateUsd(exchangeRate);
                        billingDetail.setShipType(8);
                        billingDetailsMapper.insert(billingDetail);
                    }
                    
                    // 计算总金额（RMB为基准）
                    if (currencyId == 1) {
                        totalAmount = totalAmount.add(price.multiply(shipWeigthNum));
                    } else {
                        totalAmount = totalAmount.add(price.multiply(shipWeigthNum).multiply(exchangeRate));
                    }
                }
                
                // 更新账单总金额
                LxBillingList billing = billingListMapper.selectById(billingId);
                if (billing != null) {
                    billing.setTotalAmount(totalAmount);
                    billingListMapper.updateById(billing);
                }
                
                // 更新服务账单金额
                service.setBillingAmount(totalAmount);
                serviceListMapper.updateById(service);
            }
            
            return true;
        } catch (Exception e) {
            log.error("保存账单失败", e);
            throw new RuntimeException("保存账单失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBillingDetailItem(Long detailId) {
        try {
            LxBillingDetails detail = billingDetailsMapper.selectById(detailId);
            if (detail == null) {
                return false;
            }
            
            Long billId = detail.getBillId();
            Long orderId = detail.getOrderId();
            
            // 删除明细
            billingDetailsMapper.deleteById(detailId);
            
            // 重新计算账单总金额
            QueryWrapper<LxBillingDetails> wrapper = new QueryWrapper<>();
            wrapper.eq("bill_id", billId);
            List<LxBillingDetails> remainingDetails = billingDetailsMapper.selectList(wrapper);
            
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (LxBillingDetails d : remainingDetails) {
                if (d.getCurrencyId() == 1) {
                    totalAmount = totalAmount.add(d.getPrice().multiply(d.getShipWeigthNum()));
                } else {
                    totalAmount = totalAmount.add(d.getPrice().multiply(d.getShipWeigthNum()).multiply(d.getExchangeRateSar()));
                }
            }
            
            // 更新账单总金额
            LxBillingList billing = billingListMapper.selectById(billId);
            if (billing != null) {
                billing.setTotalAmount(totalAmount);
                billingListMapper.updateById(billing);
            }
            
            // 更新服务账单金额
            if (orderId != null) {
                LxServiceList service = serviceListMapper.selectById(orderId);
                if (service != null) {
                    service.setBillingAmount(totalAmount);
                    serviceListMapper.updateById(service);
                }
            }
            
            return true;
        } catch (Exception e) {
            log.error("删除账单明细项失败", e);
            return false;
        }
    }
}

